package com.example.pacs.dicom.server.cfind;

import com.example.pacs.bean.request.QueryParamsRequest;
import com.example.pacs.bean.response.WorkListResponse;
import com.example.pacs.dao.DicomServerMapper;
import org.dcm4che3.data.Attributes;
import org.dcm4che3.data.Tag;
import org.dcm4che3.data.VR;
import org.dcm4che3.net.Association;
import org.dcm4che3.net.pdu.PresentationContext;
import org.dcm4che3.net.service.BasicQueryTask;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * worklist 查询任务类
 */
public class MWLQueryTask extends BasicQueryTask {

    private final DicomServerMapper dicomServerMapper;

    private final QueryParamsRequest params;

    private WorkListResponse response;

    private CountDownLatch countDownLatch;

    public MWLQueryTask(Association as, PresentationContext pc, Attributes rq, Attributes keys, DicomServerMapper dicomServerMapper, QueryParamsRequest params) {
        super(as, pc, rq, keys);
        this.dicomServerMapper = dicomServerMapper;
        this.params = params;
    }

    @Override
    public void run() {
        // 执行查询
        List<WorkListResponse> workListResponses = dicomServerMapper.workListByCondition(params);
        if (!CollectionUtils.isEmpty(workListResponses)) {
            // 初始化计数器为数组长度
            this.countDownLatch = new CountDownLatch(workListResponses.size());
            for (WorkListResponse response : workListResponses) {
                run0(response);
            }
        }
    }

    public void run0(WorkListResponse response) {
        this.response = response;
        // 执行父类的run方法写入返回,但是run方法中调用的部分方法是本类重写的方法
        super.run();
    }

    /**
     * 重写计算匹配方法
     *
     * @return 返回填充完数据的attributes
     */
    @Override
    protected Attributes nextMatch() {
        Attributes attributes = new Attributes();
        // 填充返回attributes使用编码格式
        attributes.setString(Tag.SpecificCharacterSet, VR.CS, "ISO_IR 100", "GB18030");
        // 填充业务信息
        attributes.setString(Tag.PatientName, VR.PN, response.getPatientName());
        attributes.setString(Tag.PatientID, VR.LO, response.getPatientId());
        attributes.setString(Tag.PatientAge, VR.AS, response.getPatientAge());
        attributes.setString(Tag.PatientSex, VR.CS, response.getPatientSex());
        attributes.setDate(Tag.PatientBirthDate, VR.DA, response.getPatientBirthday());
        attributes.setString(Tag.StudyID, VR.SH, response.getStudyId());
        attributes.setString(Tag.StudyDescription, VR.LO, response.getStudyDescription());
        attributes.setString(Tag.StudyInstanceUID, VR.UI, response.getStudyInstanceUid());
        attributes.setString(Tag.StudyStatusID, VR.CS, response.getStudyStatusId());
        attributes.setDate(Tag.StudyDateAndTime, response.getStudyDateTime());
        attributes.setString(Tag.AccessionNumber, VR.LO, response.getAccessionNumber());
        attributes.setString(Tag.AdditionalPatientHistory, VR.LT, response.getAdditionalPatientHistory());
        attributes.setString(Tag.AdmittingDiagnosesDescription, VR.LO, response.getAdmittingDiagnosesDescription());
        return attributes;
    }

    @Override
    protected boolean hasMoreMatches() {
        // 写入返回时判断是否还需要处理数据
        if (this.countDownLatch.getCount() == 0) {
            return false;
        }
        // 处理一条数据计数-1
        this.countDownLatch.countDown();
        return true;
    }

    @Override
    protected Attributes adjust(Attributes match) {
        // 判断填充数据是否为空,为空返回null
        if (match == null)
            return null;
        Attributes filtered = new Attributes(match.size());
        // 当keys不包含数据编码时从填充数据中获取
        if (!keys.contains(Tag.SpecificCharacterSet)) {
            String[] ss = match.getStrings(Tag.SpecificCharacterSet);
            if (ss != null)
                filtered.setString(Tag.SpecificCharacterSet, VR.CS, ss);
        }
        // 这里把填充数据全部返回,selected方法无法返回查询不在selection字段
        filtered.addAll(keys);
        filtered.addAll(match);
        return filtered;
    }
}
